<template>
  <div>
    <el-collapse>
      <el-collapse-item title="任务参与人配置">
        <el-form-item label="选择处理人">
          <div style="display: flex">
            <el-input v-model="elementAssignee" :disabled="true" />
            <el-button icon="Search" type="primary" @click="showAssigneeSelector = true">选择</el-button>
          </div>
        </el-form-item>
        <el-form-item label="跳过表达式">
          <el-input v-model="elementSkipExpression" @change="updateElementSkipExpression" />
        </el-form-item>
        <el-form-item label="超时设置">
          <div style="display: flex">
            <el-input v-model="elementTime" :disabled="true" />
            <el-button icon="Search" type="primary" @click="openTimeSelector">选择</el-button>
          </div>
        </el-form-item>
      </el-collapse-item>
      <el-collapse-item title="多实例信息">
        <el-form-item label="多实例类型">
          <el-radio-group v-model="elementCountersignType" @change="handleCountersignTypeChange">
            <el-radio-button label="无" value="null" />
            <el-radio-button label="并行" value="parallel" />
            <el-radio-button label="串行" value="sequential" />
          </el-radio-group>
        </el-form-item>
        <!-- <el-form-item label="是否会签">
          <el-switch v-model="isCountersign" @change="handleIsCountersignChange" />
        </el-form-item>
        <template v-if="isCountersign">
          <el-form-item label="会签类型">
            <el-radio-group v-model="elementCountersignType" @change="handleCountersignTypeChange">
              <el-radio label="并行会签" value="parallel" />
              <el-radio label="串行会签" value="sequential" />
            </el-radio-group>
          </el-form-item>
        </template> -->

        <template v-if="elementCountersignType !== 'null'">
          <el-form-item label="基数">
            <el-input v-model="elementLoopCardinality" @change="updateElementLoopCardinality" />
          </el-form-item>
          <el-form-item label="集合">
            <el-input v-model="elementCollection" @change="updateElementCollection" />
          </el-form-item>
          <el-form-item label="元素变量">
            <el-input v-model="elementVariable" @change="updateElementVariable" />
          </el-form-item>
          <el-form-item label="完成条件">
            <el-radio-group v-model="completeConditionType" size="small" @change="generateElementCompleteCondition">
              <el-radio-button label="全部完成" value="all" />
              <el-radio-button label="完成百分比" value="percent" />
              <el-radio-button label="完成数" value="count" />
              <el-radio-button label="表达式" value="expression" />
            </el-radio-group>
          </el-form-item>
          <el-form-item label="百分比" v-if="completeConditionType == 'percent'">
            <div style="display: flex; align-items: center; gap: 8px">
              <el-select v-model="completeConditionOperator" style="width: 150px" @change="generateElementCompleteCondition">
                <el-option v-for="(option, index) in completeConditionOptions" :key="index" :label="option.label" :value="option.value" />
              </el-select>
              <el-input-number v-model="completeConditionExpression" controls-position="right" @change="generateElementCompleteCondition" />
              <span>%</span>
            </div>
          </el-form-item>
          <el-form-item label="完成数" v-if="completeConditionType == 'count'">
            <div style="display: flex; align-items: center; gap: 8px">
              <el-select v-model="completeConditionOperator" style="width: 150px" @change="generateElementCompleteCondition">
                <el-option v-for="(option, index) in completeConditionOptions" :key="index" :label="option.label" :value="option.value" />
              </el-select>
              <el-input-number v-model="completeConditionExpression" controls-position="right" @change="generateElementCompleteCondition" />
            </div>
          </el-form-item>
          <el-form-item label="表达式" v-if="completeConditionType == 'expression'">
            <el-input v-model="completeConditionExpression" @change="generateElementCompleteCondition" />
          </el-form-item>
        </template>
      </el-collapse-item>
    </el-collapse>

    <drag-dialog v-model="showAssigneeSelector" width="1200px" title="选择处理人">
      <assignee-selector v-model="candidateUsers" />
      <template #footer>
        <dialog-footer @ok="submit" @cancel="cancel"></dialog-footer>
      </template>
    </drag-dialog>

    <drag-dialog v-model="showTimeSelector" width="800px" title="到期时间">
      <time-selector v-model="editTime" />
      <template #footer>
        <dialog-footer @ok="submitTime" @cancel="cancelTime"></dialog-footer>
      </template>
    </drag-dialog>
  </div>
</template>
  
  <script lang="ts">
import { defineComponent } from 'vue';
import { mapState } from 'pinia';
import modelerStore from '@wf/components/bpmnjs/store/modeler';
import { Element } from 'diagram-js/lib/model/Types';
import {
  getAssigneeValue,
  setAssigneeValue,
  setLoopCharacteristics,
  updateLoopCharacteristics,
  getLoopCharacteristics,
  setCompleteConditionValue,
  getCompleteConditionValue,
  getSkipExpressionValue,
  setSkipExpressionValue,
  getCollectionValue,
  setCollectionValue,
  getVariableValue,
  setVariableValue,
  getLoopCardinalityValue,
  setLoopCardinalityValue,
  getDueDateValue,
  setDueDateValue
} from '@wf/components/bpmnjs/bo-utils/assigneeUtil';
import EventEmitter from '@wf/components/bpmnjs/utils/EventEmitter';
import AssigneeSelector from '../../common/AssigneeSelector.vue';
import TimeSelector from '../../common/TimeSelector.vue';
import { cloneDeep } from 'lodash-es';

export default defineComponent({
  name: 'ElementAssignee',
  components: { AssigneeSelector, TimeSelector },
  data() {
    return {
      elementAssignee: '',
      elementCountersignType: '',
      elementCompleteCondition: '',
      elementSkipExpression: '',
      elementLoopCardinality: '',
      elementCollection: '',
      elementVariable: '',
      completeConditionType: '',
      completeConditionExpression: '',
      completeConditionOperator: '==',
      completeConditionOptions: [
        {
          label: '大于',
          value: '>'
        },
        {
          label: '大于等于',
          value: '>='
        },
        {
          label: '等于',
          value: '=='
        },
        {
          label: '小于',
          value: '<'
        },
        {
          label: '小于等于',
          value: '<='
        }
      ],
      originCandidates: [],
      candidateUsers: [],
      showAssigneeSelector: false,
      showTimeSelector: false,
      elementTime: '',
      editTime: ''
    };
  },
  computed: {
    ...mapState(modelerStore, ['getActive', 'getActiveId'])
  },
  watch: {
    getActiveId: {
      immediate: true,
      handler() {
        this.elementAssignee = getAssigneeValue(this.getActive as Element) || '';
        this.elementCountersignType = this.getElementCountersignType();
      }
    },
    elementAssignee: {
      handler(newVal) {
        this.watchAssigneeChange(newVal);
      },
      immediate: true
    },
    elementCountersignType: {
      handler(newVal) {
        if (newVal !== 'null') {
          this.completeConditionType = 'expression';
          this.completeConditionExpression = getCompleteConditionValue(this.getActive as Element);
        }
      },
      immediate: true
    },
    elementCompleteCondition(value) {
      this.handleCompleteConditionChange(value);
    }
  },
  mounted() {
    this.elementAssignee = getAssigneeValue(this.getActive as Element) || '';
    this.elementSkipExpression = getSkipExpressionValue(this.getActive as Element) || '';
    this.elementLoopCardinality = getLoopCardinalityValue(this.getActive as Element) || '';
    this.elementCollection = getCollectionValue(this.getActive as Element) || '';
    this.elementVariable = getVariableValue(this.getActive as Element) || '';
    this.elementTime = getDueDateValue(this.getActive as Element) || '';
    EventEmitter.on('element-update', () => {
      this.elementAssignee = getAssigneeValue(this.getActive as Element) || '';
    });
  },
  methods: {
    updateAssignee(value) {
      setAssigneeValue(this.getActive as Element, value);
      this.handleCountersignTypeChange(this.elementCountersignType);
    },
    submit() {
      this.originCandidates = this.candidateUsers;
      this.elementAssignee = this.candidateUsers.map((user: any) => user.value).join(',');
      this.updateAssignee(this.elementAssignee);
      this.cancel();
    },
    cancel() {
      this.showAssigneeSelector = false;
      this.cloneCandidates();
    },
    cloneCandidates() {
      this.candidateUsers = cloneDeep(this.originCandidates);
    },
    getElementCountersignType() {
      const loopCharacteristics = getLoopCharacteristics(this.getActive as Element);
      return loopCharacteristics ? (loopCharacteristics.isSequential ? 'sequential' : 'parallel') : 'null';
    },
    handleCountersignTypeChange(value: string) {
      if (value == 'null') {
        updateLoopCharacteristics(this.getActive as Element);
      } else if (value == 'sequential') {
        setLoopCharacteristics(this.getActive as Element, { isSequential: true });
      } else {
        setLoopCharacteristics(this.getActive as Element);
      }
    },
    handleCompleteConditionChange(value: string) {
      setCompleteConditionValue(this.getActive as Element, value);
    },
    watchAssigneeChange(newVal: string) {
      if (newVal) {
        this.originCandidates = newVal.split(',').map((v: any) => {
          return {
            value: v,
            isEdit: false
          };
        });
      } else {
        this.originCandidates = [];
      }
      this.cloneCandidates();
    },
    updateElementSkipExpression(value: string) {
      setSkipExpressionValue(this.getActive as Element, value);
    },
    updateElementLoopCardinality(value: string) {
      setLoopCardinalityValue(this.getActive as Element, value);
    },
    updateElementCollection(value: string) {
      setCollectionValue(this.getActive as Element, value);
    },
    updateElementVariable(value: string) {
      setVariableValue(this.getActive as Element, value);
    },
    generateElementCompleteCondition() {
      if (this.completeConditionType == 'all') {
        this.elementCompleteCondition = '${nrOfCompletedInstances/nrOfInstances==1}';
      } else if (this.completeConditionType == 'percent') {
        this.elementCompleteCondition = '${nrOfCompletedInstances/nrOfInstances' + this.completeConditionOperator + Number(this.completeConditionExpression) / 100 + '}';
      } else if (this.completeConditionType == 'count') {
        this.elementCompleteCondition = '${nrOfCompletedInstances' + this.completeConditionOperator + this.completeConditionExpression + '}';
      } else if (this.completeConditionType == 'expression') {
        this.elementCompleteCondition = this.completeConditionExpression;
      }
    },
    openTimeSelector() {
      this.editTime = this.elementTime;
      this.showTimeSelector = true;
    },
    submitTime() {
      setDueDateValue(this.getActive as Element, this.editTime);
      this.elementTime = getDueDateValue(this.getActive as Element);
      this.cancelTime();
    },
    cancelTime() {
      this.showTimeSelector = false;
    }
  }
});
</script>
  